﻿// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "LPC/tcpclient.h"
#include "SafeBox.h"
#include "SafeBoxInterface.h"
#include <Unknwnbase.h>

HMODULE gModule = NULL;

// 类工厂
class CSafeBoxClassFactory : public IClassFactory {
public:
    CSafeBoxClassFactory() : m_refCount(1) {}

    HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) override {
        if (riid == IID_IUnknown || riid == IID_IClassFactory) {
            *ppvObject = static_cast<IClassFactory*>(this);
            AddRef();
            return S_OK;
        }
        *ppvObject = nullptr;
        return E_NOINTERFACE;
    }

    ULONG STDMETHODCALLTYPE AddRef() override {
        return InterlockedIncrement(&m_refCount);
    }

    ULONG STDMETHODCALLTYPE Release() override {
        ULONG refCount = InterlockedDecrement(&m_refCount);
        if (refCount == 0) {
            delete this;
        }
        return refCount;
    }

    HRESULT STDMETHODCALLTYPE CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppvObject) override {
        if (pUnkOuter != nullptr) {
            return CLASS_E_NOAGGREGATION;
        }

        if (ppvObject == nullptr) {
            return E_POINTER;
        }

        IUnknown* pObject = nullptr;
        HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
        if (IsEqualCLSID(riid, __uuidof(ISafeBoxInterface))) {
            pObject = reinterpret_cast<IUnknown*>(new ISafeBoxInterface);
        }
        else {
            return CLASS_E_CLASSNOTAVAILABLE;
        }

        if (pObject == nullptr) {
            return E_OUTOFMEMORY;
        }

        hr = pObject->QueryInterface(riid, ppvObject);
        pObject->Release();

        return hr;
    }

    HRESULT STDMETHODCALLTYPE LockServer(BOOL fLock) override {
        if (fLock) {
            InterlockedIncrement(&m_serverLocks);
        }
        else {
            InterlockedDecrement(&m_serverLocks);
        }
        return S_OK;
    }

public:
    LONG m_refCount;
    static LONG m_serverLocks;
};

LONG CSafeBoxClassFactory::m_serverLocks = 0;

// DLL 导出函数
HRESULT STDMETHODCALLTYPE DllGetClassObject(REFCLSID rclsid, REFIID riid, void** ppv) {
    static CSafeBoxClassFactory factory;
    return factory.QueryInterface(riid, ppv);
}

HRESULT STDMETHODCALLTYPE DllCanUnloadNow() {
    return (CSafeBoxClassFactory::m_serverLocks == 0) ? S_OK : S_FALSE;
}



BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    {
        ProcessAttach(hModule);
    }break; 
    case DLL_THREAD_ATTACH:
    {
        int a = 0;
    }break;
    case DLL_THREAD_DETACH:
    {
        TcpThreadDetach(GetCurrentThreadId());
    }break;
    case DLL_PROCESS_DETACH:
    {
        ProcessDetach(hModule);
        TcpReleaseLpcData();
    }break;
    }
    return TRUE;
}

